import { BUTTON_LS, BUTTON_RS } from "./constants";

// 定义常量
const ERROR_CODES = {
  NOT_CONFIGURED: '501',
  SUCCESS: '200',
  NOT_FOUND: '404'
};

const ERROR_MESSAGES = {
  NOT_CONFIGURED: '未配置',
  SUCCESS: 'success',
  NOT_FOUND: '未找到匹配的配置'
};

const ACTION_TYPES = {
  DOWN: 'down',
  UP: 'up',
  MOVE: 'move'
};

// 方向键常量定义
const DPAD_UP = 12;
const DPAD_DOWN = 13;
const DPAD_LEFT = 14;
const DPAD_RIGHT = 15;
const DPAD_MOVE_STEP = 50; // 方向键移动步长

class Gamepad2Touch {
  constructor() {
    this.config = null;
    this._state = 0; // 0:未配置，1:已配置
    this.leftStick = 0; // 使用驼峰命名
    this.rightStick = 0; // 使用驼峰命名
    this.lastButton = { press: false, x: 0, y: 0, id: '' };
  }

  /**
   * 更新配置并设置状态为已配置
   * @param {Object} config - 游戏手柄配置对象
   */
  updateConfig(config) {
    this.config = config;
    this._state = 1;
  }

  /**
   * 获取当前状态
   * @returns {number} 0:未配置，1:已配置
   */
  get state() {
    return this._state;
  }

  /**
   * 创建方向键模拟摇杆事件
   * @param {number} buttonIndex - 按钮索引
   * @param {String} type - 事件类型(press/release)
   * @returns {Object} 模拟的摇杆事件
   */
  createDirectionKeyMockEvent(buttonIndex, type) {
    let axes = [0, 0, 0, 0]; // 左摇杆x, y, 右摇杆x, y
    // 获取移动模式的摇杆配置
    const moveStickConfig = this.config?.buttons?.find(btn => 
      (btn.type === 'left_stick' || btn.type === 'right_stick') && btn.mode === 'move'
    );
    if(!moveStickConfig){
      return null;
    }
    // 默认使用左摇杆，找不到配置时保持向后兼容
    const isLeftStick = moveStickConfig?.type !== 'right_stick';
    const xIndex = isLeftStick ? 0 : 2;
    const yIndex = isLeftStick ? 1 : 3;

    // 根据方向键索引设置对应摇杆轴值
    switch(buttonIndex) {
      case 12: // 上方向键
        axes[yIndex] = type === 'press' ? -1 : 0;
        break;
      case 13: // 下方向键
        axes[yIndex] = type === 'press' ? 1 : 0;
        break;
      case 14: // 左方向键
        axes[xIndex] = type === 'press' ? -1 : 0;
        break;
      case 15: // 右方向键
        axes[xIndex] = type === 'press' ? 1 : 0;
        break;
    }
    return { stickMoved: true, axes };
  }

  /**
   * 处理按钮事件
   * @param {Object} gamepadEvent - 游戏手柄事件对象
   * @param {String} type - 游戏手柄事件类型
   * @returns {Object} 处理结果
   */
  handleButtonEvent(gamepadEvent, type) {
    const buttonIndex = gamepadEvent.index;
    const buttonConfig = this.config?.buttons?.find(
      btn => btn.keycode === buttonIndex.toString() && btn.type === 'click'
    );

    // 如果有配置则使用配置，无配置则检查是否为方向键
    if (buttonConfig) {
      this.lastButton = {
      press: type === 'press',
      id: buttonIndex,
      x: buttonConfig.x,
      y: buttonConfig.y
    };
    return [{
      id: buttonIndex,
      x: buttonConfig.x,
      y: buttonConfig.y,
      action: type === 'press' ? ACTION_TYPES.DOWN : ACTION_TYPES.UP
    }];
    } else {
      // 方向键(12:上,13:下,14:左,15:右)未配置时模拟摇杆事件
      const directionKeyIndices = [12, 13, 14, 15];
      if (directionKeyIndices.includes(buttonIndex)) {
        const mockEvent = this.createDirectionKeyMockEvent(buttonIndex, type);
        return mockEvent && this.handleStickEvent(mockEvent);
      }
    }

    return null;
  }

  /**
   * 处理摇杆事件
   * @param {Object} gamepadEvent - 游戏手柄事件对象
   * @returns {Object[]} 处理后的动作数组
   */
  handleStickEvent(gamepadEvent) {
    const actions = [];
    const axes = gamepadEvent.axes;
    const leftStickValue = this.calStickAxisMovements(axes[0], axes[1]);
    const rightStickValue = this.calStickAxisMovements(axes[2], axes[3]);
    
    // 处理左摇杆
    if (leftStickValue !== this.leftStick) {
      actions.push(...this.processStickMovement(
        'left_stick', 
        leftStickValue, 
        this.leftStick, 
        axes[0], 
        axes[1]
      ));
      this.leftStick = leftStickValue;
    }

    // 处理右摇杆
    if (rightStickValue !== this.rightStick) {
      actions.push(...this.processStickMovement(
        'right_stick', 
        rightStickValue, 
        this.rightStick, 
        axes[2], 
        axes[3]
      ));
      this.rightStick = rightStickValue;
    }

    return actions;
  }

  /**
   * 处理单个摇杆移动
   * @param {string} stickType - 摇杆类型(left_stick/right_stick)
   * @param {number} currentValue - 当前摇杆值
   * @param {number} previousValue - 上一次摇杆值
   * @param {number} x - X轴值
   * @param {number} y - Y轴值
   * @returns {Object[]} 处理后的动作数组
   */
  processStickMovement(stickType, currentValue, previousValue, x, y) {
    const actions = [];
    const stickConfig = this.config?.buttons?.find(btn => btn.type === stickType);

    if (!stickConfig) return actions;

    const { mode = 'move', radius = 100 } = stickConfig;
    let baseX, baseY;

    let actionId = stickType === 'leftStick' ? BUTTON_LS : BUTTON_RS;

    // 根据模式确定中心点
    if (mode === 'skill') {
      // skill模式下检查lastButton状态
      if (!this.lastButton.press) {
        return actions; // 未按下则不处理
      }
      actionId = this.lastButton.id;
      baseX = this.lastButton.x;
      baseY = this.lastButton.y;
    } else {
      // move模式使用配置的基础坐标
      baseX = stickConfig.x;
      baseY = stickConfig.y;
    }

    const newX = baseX + (x * radius);
    const newY = baseY + (y * radius);

    // 摇杆开始移动
    if (previousValue === 0) {
      actions.push({
        type: ACTION_TYPES.DOWN,
        x: baseX,
        y: baseY,
        stick: stickType,
        id: actionId
      });
    }

    // 执行回调
    if (stickConfig.callback && typeof stickConfig.callback === 'function') {
      stickConfig.callback(currentValue);
    }

    // 摇杆移动中
    actions.push({
      type: ACTION_TYPES.MOVE,
      x: newX,
      y: newY,
      stick: stickType,
      id: actionId
    });

    // 摇杆停止移动
    if (currentValue === 0) {
      actions.push({
        type: ACTION_TYPES.UP,
        x: baseX,
        y: baseY,
        stick: stickType,
        id: actionId
      });
    }

    return actions;
  }

  /**
   * 计算摇杆移动幅度
   * @param {number} x - X轴值
   * @param {number} y - Y轴值
   * @returns {number} 移动幅度
   */
  calStickAxisMovements(x, y) {
    return Math.sqrt(x * x + y * y);
  }

  /**
   * 事件适配器主方法
   * @param {Object} gamepadEvent - 游戏手柄事件对象
   * @returns {Object} 处理结果
   */
  eventAdapter(gamepadEvent, type) {
    // 检查是否已配置
    if (this._state === 0) {
      return {
        code: ERROR_CODES.NOT_CONFIGURED,
        message: ERROR_MESSAGES.NOT_CONFIGURED
      };
    }

    let actions = [];

    // 处理按钮事件
    if (gamepadEvent.buttonName) {
      const buttonActions = this.handleButtonEvent(gamepadEvent, type);
      if (buttonActions) {
        actions = [...actions, ...buttonActions];
      }
    }
    // 处理摇杆事件
    else if (gamepadEvent.stickMoved) {
      const stickActions = this.handleStickEvent(gamepadEvent);
      if (stickActions.length > 0) {
        actions = [...actions, ...stickActions];
      }
    }

    // 返回结果
    if (actions.length > 0) {
      return {
        code: ERROR_CODES.SUCCESS,
        message: ERROR_MESSAGES.SUCCESS,
        actions
      };
    }

    // 未匹配到配置的事件
    return {
      code: ERROR_CODES.NOT_FOUND,
      eventType: gamepadEvent.type || 'unknown',
      message: ERROR_MESSAGES.NOT_FOUND
    };
  }
};


export default Gamepad2Touch